جزوه · فصل نهم · جلسه ۸۵ · نمایش وضعیت اجرای فرمان ← بازگشت به فهرست
📘 فصل نهم · جلسه ۸۵ نمایش وضعیت اجرای فرمان
📅 تاریخ: پنجشنبه، ۴ شهریور ۱۴۰۵ 👤 مدرس: محمد عابدینی 🐚 Zsh · 🐧 Debian (کالی) · 📦 Red Hat
این جلسه یکی از مباحث پایه‌ای و بسیار مهم در اسکریپت‌نویسی است. مفهوم Exit Status و استفاده از $? برای بررسی موفقیت یا شکست فرمان‌ها، در آزمون‌های LPIC و RHCSA بسیار پرتکرار است.
📊 قبل از شروع، یه مثال ساده:

فرض کن در یه مسابقه شرکت کردی. بعد از هر مرحله، بهت یه کارنامه می‌دن که توش نوشته «قبول» یا «رد». توی لینوکس، هر فرمانی که اجرا می‌شه، یه کارنامه به اسم Exit Status برمی‌گردونه که به ما می‌گه آیا فرمان موفق بوده یا ناموفق. این جلسه بهت یاد میده چطور این کارنامه رو بخونی و ازش استفاده کنی!

▍ وضعیت اجرای فرمان (Exit Status) چیست؟

هر فرمانی که در لینوکس اجرا می‌شود، پس از پایان کار، یک کد عددی به عنوان وضعیت خروج (Exit Status) به ترمینال یا فرمان والد خود ارسال می‌کند. این کد مشخص می‌کند که آیا فرمان با موفقیت اجرا شده یا با خطا مواجه شده است.

🔑 نکته کلیدی: متغیر $? آخرین وضعیت خروج (Exit Status) فرمان قبلی را در خود ذخیره می‌کند. این متغیر همیشه در حال تغییر است و با اجرای هر فرمان جدید، مقدار آن به‌روزرسانی می‌شود.
نکته امتحانی: $? یک متغیر ویژه در Bash است که همیشه آخرین کد خروجی را نگه می‌دارد.

▍ معنی اعداد Exit Status

به طور کلی، کدهای خروجی به این صورت تفسیر می‌شوند:

🟢 عدد 0

  • به معنای موفقیت است.
  • فرمان به درستی اجرا شده است.
  • مثال: ls در یک دایرکتوری موجود.

🟡 عدد 1

  • به معنای خطای عمومی است.
  • مشکل جزئی (مثلاً عدم دسترسی به زیردایرکتوری).
  • مثال: ls در دایرکتوری بدون مجوز.

🔴 عدد 2

  • به معنای خطای جدی است.
  • مشکل اساسی (مثلاً آرگومان اشتباه).
  • مثال: ls /hj (مسیر ناموجود).
نکته مهم: عدد صفر (0) همیشه به معنای موفقیت است. هر عدد غیرصفر نشان‌دهندهٔ خطا یا شکست است. اما اعداد دقیق می‌توانند بسته به فرمان متفاوت باشند.

▍ مثال‌های عملی

• مثال ۱: فرمان موفق

┌──(ya3in㉿kali)-[~] └─$ ls Desktop Documents Downloads Music Pictures Videos └─$ echo $? 0

توضیح: ls با موفقیت اجرا شده و کد خروجی 0 را برگردانده است.

• مثال ۲: فرمان ناموفق (مسیر اشتباه)

┌──(ya3in㉿kali)-[~] └─$ ls /hj ls: cannot access '/hj': No such file or directory └─$ echo $? 2

توضیح: ls /hj با خطا مواجه شده است (مسیر وجود ندارد) و کد خروجی 2 را برگردانده است.

• مثال ۳: فرمان ناموفق (مجوز کافی)

┌──(ya3in㉿kali)-[~] └─$ cat /etc/shadow cat: /etc/shadow: Permission denied └─$ echo $? 1

توضیح: cat /etc/shadow به دلیل عدم مجوز دسترسی با خطا مواجه شده و کد خروجی 1 را برگردانده است.

نکته: کد خروجی همیشه مربوط به آخرین فرمان اجرا شده است. اگر بین دو فرمان دستوری مثل echo اجرا کنید، $? مربوط به همان echo خواهد بود.

▍ استفاده از $? در اسکریپت‌ها

در اسکریپت‌نویسی، از $? برای بررسی موفقیت یا شکست یک فرمان استفاده می‌کنیم و بر اساس آن تصمیم‌گیری می‌کنیم.

#!/bin/bash # بررسی وضعیت اجرای فرمان mkdir mkdir test_dir if [ $? -eq 0 ]; then echo "دایرکتوری با موفقیت ساخته شد." else echo "خطا در ایجاد دایرکتوری!" fi
┌──(ya3in㉿kali)-[~] └─$ ./check_mkdir.sh دایرکتوری با موفقیت ساخته شد.

توضیح: اسکریپت ابتدا mkdir را اجرا می‌کند، سپس با $? وضعیت آن را بررسی می‌کند و پیام مناسب را چاپ می‌کند.

• استفاده از || و && با $?

عملگرهای && و || در واقع بر اساس کد خروجی فرمان‌ها کار می‌کنند.

┌──(ya3in㉿kali)-[~] └─$ mkdir new_folder && echo "ساخته شد" ساخته شد

توضیح: اگر mkdir موفق باشد ($? = 0)، عبارت بعد از && اجرا می‌شود.

┌──(ya3in㉿kali)-[~] └─$ mkdir existing_folder || echo "خطا: دایرکتوری وجود دارد" خطا: دایرکتوری وجود دارد

توضیح: اگر mkdir شکست بخورد ($? ≠ 0)، عبارت بعد از || اجرا می‌شود.

نکته امتحانی: && و || در واقع بر اساس کد خروجی فرمان اول تصمیم می‌گیرند که فرمان دوم را اجرا کنند یا نه.

▍ کدهای خروجی خاص در برخی فرمان‌ها

برخی فرمان‌ها برای خطاهای مختلف، کدهای خروجی متفاوتی دارند. برای مثال، دستور ls:

کد خروجی معنی در ls
0 موفقیت (OK)
1 مشکل جزئی (مثلاً عدم دسترسی به زیردایرکتوری)
2 مشکل جدی (مثلاً آرگومان خط فرمان نامعتبر)

برای اطلاع از کدهای خروجی دقیق هر فرمان، می‌توانید به صفحه راهنما (man) آن فرمان مراجعه کنید.

┌──(ya3in㉿kali)-[~] └─$ man ls # سپس به بخش "EXIT STATUS" بروید
💡 نکته: در صفحات راهنمای (man) اکثر فرمان‌ها، بخش EXIT STATUS توضیح می‌دهد که هر کد خروجی چه معنایی دارد.

▍ جمع‌بندی و نکات مهم

✅ جمع‌بندی نهایی:
  • Exit Status → کد عددی که هر فرمان پس از اجرا برمی‌گرداند.
  • $? → متغیر ویژه برای دسترسی به آخرین کد خروجی.
  • 0 → یعنی فرمان موفق بوده است.
  • غیر از 0 → یعنی فرمان ناموفق بوده است (نوع خطا بسته به فرمان متفاوت است).
  • && → اگر فرمان اول موفق باشد ($? = 0)، فرمان دوم را اجرا کن.
  • || → اگر فرمان اول ناموفق باشد ($? ≠ 0)، فرمان دوم را اجرا کن.
  • کاربرد: برای مدیریت خطا و کنترل جریان در اسکریپت‌ها بسیار مهم است.
📝 تمرین پیشنهادی:

یک اسکریپت بنویسید که:

  • از کاربر یک مسیر (دایرکتوری) بگیرد.
  • با cd به آن مسیر برود.
  • با $? وضعیت را بررسی کند.
  • اگر موفق بود، پیام «ورود به دایرکتوری موفق» و لیست فایل‌ها را چاپ کند.
  • اگر ناموفق بود، پیام «خطا: دایرکتوری وجود ندارد» را چاپ کند.